package com.united.ucts.modules.system.controller;

import cn.hutool.core.collection.CollUtil;
import com.united.frame.common.module.result.PageResult;
import com.united.frame.common.module.result.Result;
import com.united.frame.plugin.restfull.response.NotControllerResponseAdvice;
import com.united.frame.plugin.security.CurrUser;
import com.united.frame.plugin.security.Oauth2Token;
import com.united.ucts.common.constant.AdminConstant;
import com.united.ucts.modules.system.pojo.dto.AdminDto;
import com.united.ucts.modules.system.pojo.dto.AdminLoginParamDto;
import com.united.ucts.modules.system.pojo.dto.AdminParamDto;
import com.united.ucts.modules.system.pojo.dto.AdminPasswordUpdateParamDto;
import com.united.ucts.modules.system.pojo.po.Admin;
import com.united.ucts.modules.system.pojo.po.Role;
import com.united.ucts.modules.system.service.AdminService;
import com.united.ucts.modules.system.service.RoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 后台用户管理控制器
 *
 * @author Hudan
 * @version 1.0
 * @filename AdminController.java
 * @copyright <a href="www.united.cn">www.united.cn</a>
 * @date 2019-08-16
 */
@Slf4j
@RequiredArgsConstructor
@Api(tags = "AdminController", value = "后台用户管理")
@RestController
@RequestMapping("/admin")
public class AdminController {
    private final AdminService adminService;
    private final RoleService roleService;

    /**
     * 后台用户注册
     *
     * @param param 后台用户注册请求信息
     * @return 注册结果
     */
    @ApiOperation(value = "用户注册")
    @PostMapping(value = "/register")
    public Result<Admin> register(@Valid @RequestBody AdminParamDto param) {
        Admin admin = adminService.register(param);
        if (Objects.isNull(admin)) {
            return Result.failure();
        }
        return Result.success(admin);
    }

    /**
     * 删除指定的后台用户
     *
     * @param id 需要删除的后台用户ID
     * @return 删除结果
     */
    @ApiOperation("删除指定的后台用户信息")
    @PostMapping(value = "/delete/{id}")
    public Result<Boolean> delete(@PathVariable String id) {
        boolean result = adminService.delete(id);
        if (result) {
            return Result.success(result);
        }
        return Result.failure();
    }

    /**
     * 修改指定后台用户信息
     *
     * @param id    需要修改的后台用户ID
     * @param admin 具体修改信息
     * @return 修改结果
     */
    @ApiOperation("修改指定的后台用户信息 ")
    @PostMapping(value = "/update/{id}")
    public Result<Boolean> update(@PathVariable String id, @Valid @RequestBody Admin admin) {
        boolean result = adminService.update(id, admin);
        if (result) {
            return Result.success(result);
        }
        return Result.failure();
    }

    /**
     * 获取指定后台用户信息
     *
     * @param id 需要获取的后台用户ID
     * @return 用户详情信息
     */
    @ApiOperation("获取指定的后台用户信息")
    @GetMapping(value = "/{id}")
    public Result<Admin> getItem(@PathVariable String id) {
        Admin admin = adminService.getItem(id);
        return Result.success(admin);
    }

    /**
     * 根据用户名或姓名分页获取后台用户信息分页列表
     *
     * @param pageNum  页数
     * @param pageSize 每页大小
     * @param keyword  查询关键字(用户名/姓名)
     * @return 后台用户信息分页列表
     */
    @ApiOperation("根据用户名或姓名分页获取后台用户列表")
    @GetMapping(value = "/list")
    public Result<PageResult<AdminDto>> pageBy(@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
                                               @RequestParam(value = "pageSize", defaultValue = "5") Integer pageSize,
                                               @RequestParam(value = "keyword", required = false) String keyword) {
        // 分页查询获取相应分页数据
        List<AdminDto> result = adminService.pageBy(pageNum, pageSize, keyword);

        return Result.success(PageResult.restPage(result));
    }

    /**
     * 修改指定后台用户密码
     *
     * @param param 密码修改请求参数
     * @return 修改结果
     */
    @ApiOperation("修改指定后台用户密码")
    @PostMapping(value = "/updatePassword")
    public Result<Integer> updatePassword(@Valid @RequestBody AdminPasswordUpdateParamDto param) {
        int status = adminService.updatePassword(param);
        if (status > 0) {
            return Result.success(status);
        } else if (status == -1) {
            return Result.failure("提交参数不合法");
        } else if (status == -2) {
            return Result.failure("找不到该用户");
        } else if (status == -3) {
            return Result.failure("旧密码错误");
        } else {
            return Result.failure();
        }
    }

    @ApiOperation("修改帐号状态")
    @PostMapping(value = "/updateStatus/{id}")
    public Result<Boolean> updateStatus(@PathVariable String id, @RequestParam(value = "status") Integer status) {
        Admin admin = new Admin();
        admin.setStatus(status);
        boolean result = adminService.update(id, admin);
        if (result) {
            return Result.success(result);
        }
        return Result.failure();
    }

    @ApiOperation("给用户分配角色")
    @PostMapping(value = "/role/update")
    public Result<Integer> updateRole(@RequestParam("adminId") String adminId,
                                      @RequestParam("roleIds") List<String> roleIds) {
        int count = adminService.updateRole(adminId, roleIds);
        if (count >= 0) {
            return Result.success(count);
        }
        return Result.failure();
    }

    /**
     * 后台用户登录
     *
     * @param param 登录请求参数
     * @return 登录结果
     */
    @ApiOperation(value = "登录以后返回token")
    @PostMapping(value = "/login")
    public Result<Oauth2Token> login(@Valid @RequestBody AdminLoginParamDto param) {
        return adminService.login(param.getUsername(), param.getPassword());
    }

    /**
     * 用户登出
     *
     * @return 登出结果
     */
    @ApiOperation(value = "登出功能")
    @PostMapping(value = "/logout")
    public Result<Void> logout() {
        return Result.success();
    }

    /**
     * 获取当前登录用户信息
     *
     * @return 当前登录用户信息
     */
    @ApiOperation(value = "获取当前登录用户信息")
    @GetMapping(value = "/info")
    public Result<Map<String, Object>> getAdminInfo() {
        // 获取当前登录用户信息
        Admin admin = adminService.getCurrentAdmin();

        /* 组装当前登录用户其他要素信息 */
        Map<String, Object> data = new HashMap<>(4);
        data.put(AdminConstant.ADMIN_USER_NAME, admin.getUsername());
        data.put(AdminConstant.ADMIN_USER_ICON, admin.getIcon());
        // 获取用户权限菜单信息
        data.put(AdminConstant.ADMIN_USER_MENUS, roleService.getMenuList(admin.getId()));
        // 获取用户角色信息
        List<Role> roles = adminService.getRoleList(admin.getId());
        if (CollUtil.isNotEmpty(roles)) {
            data.put(AdminConstant.ADMIN_USER_ROLES, roles.stream().map(Role::getName).collect(Collectors.toList()));
        }
        return Result.success(data);
    }

    @ApiOperation("获取指定用户的角色")
    @GetMapping(value = "/role/{adminId}")
    public Result<List<Role>> getRoleList(@PathVariable String adminId) {
        List<Role> roleList = adminService.getRoleList(adminId);
        return Result.success(roleList);
    }

    @ApiOperation("根据用户名获取通用用户信息")
    @GetMapping(value = "/loadByUsername")
    @NotControllerResponseAdvice
    public CurrUser loadUserByUsername(@RequestParam String username) {
        return adminService.loadUserByUsername(username);
    }
}